// 单例模式的思路是：保证一个类只能被实例一次，每次获取的时候，如果该类已经创建过实例则直接返回该实例，否则创建一个实例保存并返回。
// 单例模式的核心就是创建一个唯一的对象，而在javascript中创建一个唯一的对象太简单了，为了获取一个对象而去创建一个类有点多此一举。如const obj = {}，obj就是独一无二的一个对象，在全局作用域的声明下，可以在任何地方对它访问，这就满足了单例模式的条件。

// 优点
// 1 内存中只有一个实例，减少了内存的开销。
// 2 避免了对资源多重的占用。

// 缺点
// 违反了单一职责，一个类应该只关心内部逻辑，而不用去关心外部的实现

// 例子
// 我们常见到的登录弹窗，要么显示要么隐藏，不可能同时出现两个弹窗，下面我们通过一个类来模拟弹窗。
class LoginFrame {
  static instance = null;

  constructor(state) {
    this.state = state;
  }

  show() {
    if (this.state === 'show') {
      console.log('登录框已显示');
      return;
    }
    this.state = 'show';
    console.log('登录框展示成功');
  }

  hide() {
    if (this.state === 'hide') {
      console.log('登录框已隐藏');
      return;
    }
    this.state = 'hide';
    console.log('登录框隐藏成功');
  }

  // 通过静态方法获取静态属性instance上是否存在实例，如果没有创建一个并返回，反之直接返回已有的实例
  static getInstance(state) {
    if (!this.instance) {
      this.instance = new LoginFrame(state);
    }

    return this.instance;
  }
}

const p1 = LoginFrame.getInstance('show');
const p2 = LoginFrame.getInstance('hide');
console.log(p1 === p2); // true
